package com.ubb.damate.service.impl;

import java.util.Date;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import com.ubb.damate.util.DateUtils;
import com.ubb.damate.model.EclipseUsageModel;
import com.ubb.damate.model.User;
import com.ubb.damate.model.Workspace;
import com.ubb.damate.model.Event;
import com.ubb.damate.model.UserEvent;
import com.ubb.damate.model.UserEventPK;
import com.ubb.damate.service.EclipseUsageServiceLocal;
import com.ubb.damate.service.EclipseUsageServiceRemote;
import com.ubb.damate.service.UserServiceLocal;
import com.ubb.damate.service.WorkspaceServiceLocal;

/** Session Bean implementation class EclipseUsageService */
@Stateless
public class EclipseUsageService implements EclipseUsageServiceRemote, EclipseUsageServiceLocal {

	@PersistenceContext(unitName = "damate-pu")
	private EntityManager		em;

	@EJB(beanName = "UserService")
	private UserServiceLocal	userService;
	
	@EJB(beanName = "WorkspaceService")
	private WorkspaceServiceLocal workspaceService;

	public Map<User, EclipseUsageModel> getStats() {
		Map<User, EclipseUsageModel> result = new HashMap<User, EclipseUsageModel>();
		List<User> users = userService.allUser();
		for (User user : users) {
			result.put(user, getStats(user));
		}

		/*String username = "";
		String path = "";

		CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
		CriteriaQuery<Workspace> criteriaQuery = criteriaBuilder.createQuery(Workspace.class);
		Root<Workspace> from = criteriaQuery.from(Workspace.class);
		Predicate condition = criteriaBuilder.equal(from.get("username"), username);
		Predicate condition2 = criteriaBuilder.equal(from.get("path"), path);
		Predicate condition3 = criteriaBuilder.and(condition, condition2);
		criteriaQuery.where(condition3);
		Query query = em.createQuery(criteriaQuery);*/
		//return (Workspace) query.getSingleResult();

		return result;
	}
	
	
	public EclipseUsageModel getStats(User user) {
		EclipseUsageModel eum = new EclipseUsageModel();
		List<Integer> openSeconds = new ArrayList<Integer>();
		List<Integer> changes = new ArrayList<Integer>();
		List<Integer> projects = new ArrayList<Integer>();
		String username = user.getUsername();
		
		Date date1, date2;
		int i, j, value;
		Date date;
		Event event;
		UserEventPK userEventPK;
		List<Workspace> workSpaces;
		//CriteriaBuilder criteriaBuilder;
		//CriteriaQuery<UserEvent> criteriaQuery;
		//Root<UserEvent> from;
		//Expression<String> literal;
		//Predicate condition, condition2, condition3, condition4, condition5;
		Query query;
		List<String> userEvents;
		
		// eclipse was opened per month
		for (i = 1; i <= Calendar.MONTH; i++)
		{
			value = 0;
			for (j = 1; j <= 31; j++) {
				date = DateUtils.createDate(-1, i, j);
				
				//criteriaBuilder = em.getCriteriaBuilder();
				//criteriaQuery = criteriaBuilder.createQuery(UserEvent.class);
				//from = criteriaQuery.from(UserEvent.class);
				
				//literal = criteriaBuilder.upper(criteriaBuilder.literal((String) username));
				//condition = criteriaBuilder.like(criteriaBuilder.upper(from.get("username")), literal);
				//condition2 = criteriaBuilder.equal(from.get("eventname"), "opentime");
				//condition3 = criteriaBuilder.equal(from.get("eventdate"), date);
				//condition4 = criteriaBuilder.and(condition, condition2);
				//condition5 = criteriaBuilder.and(condition4, condition3);
				
				//criteriaQuery.where(condition);
				//query = em.createQuery(criteriaQuery);
				
				event = new Event();
				event.setEventName("OpenTime");
				
				userEventPK = new UserEventPK();
				userEventPK.setUsername(user.getUsername());
				userEventPK.setEventname("OpenTime");
				userEventPK.setEventdate(date);
				
				query = em.createQuery("select u.eventvalue from UserEvent u where u.user=:arg1 and u.event=:arg2 and u.id=:arg3");
				query.setParameter("arg1", user);
				query.setParameter("arg2", event);
				query.setParameter("arg3", userEventPK);
				
				userEvents = query.getResultList();
				if(userEvents.size() > 0) {
					try {
						value += Integer.parseInt(userEvents.get(0));
					}
					catch (Exception e)
					{}
				}
			}
			openSeconds.add(value);
		}
		while (openSeconds.size() < 12)
			openSeconds.add(0);
		
		// window changes per month
		for (i = 1; i <= Calendar.MONTH; i++)
		{
			value = 0;
			for (j = 1; j <= 31; j++) {
				date = DateUtils.createDate(-1, i, j);
				
				event = new Event();
				event.setEventName("Change");
				
				userEventPK = new UserEventPK();
				userEventPK.setUsername(user.getUsername());
				userEventPK.setEventname("Change");
				userEventPK.setEventdate(date);
				
				query = em.createQuery("select u.eventvalue from UserEvent u where u.user=:arg1 and u.event=:arg2 and u.id=:arg3");
				query.setParameter("arg1", user);
				query.setParameter("arg2", event);
				query.setParameter("arg3", userEventPK);
				
				userEvents = query.getResultList();
				if(userEvents.size() > 0) {
					try {
						value += Integer.parseInt(userEvents.get(0));
					}
					catch (Exception e)
					{}
				}
			}
			changes.add(value);
		}
		while (changes.size() < 12)
			changes.add(0);
		
		// projects added per month
		for (i = 1; i <= Calendar.MONTH; i++)
		{
			value = 0;
			for (j = 1; j <= 31; j++) {
				date = DateUtils.createDate(-1, i, j);
				
				workSpaces = workspaceService.find(user.getUsername());
				
				for (Workspace workSpace : workSpaces) {
					query = em.createQuery("select count(p.id) from Project p where p.creationDate=:arg1 and p.workspace=:arg2");
					query.setParameter("arg1", date);
					query.setParameter("arg2", workSpace);
					
					try
					{
						value += Integer.parseInt("" + (Long)query.getSingleResult());
					}
					catch(Exception e)
					{}
				}
			}
			projects.add(value);
		}
		while (projects.size() < 12)
			projects.add(0);
		
		eum.setOpenSeconds(openSeconds);
		eum.setChanges(changes);
		eum.setProjects(projects);
		
		return eum;
	}
}